一個XR就是沉浸感體驗,效能好只是增加好的體驗,想要有沉浸感,融入場景的3D按鈕互動才是能帶來沉浸感的精隨。就像總不能為了省錢就餐餐只吃最低預算過活,還是要保留一點生活體驗才活得像人對吧。
在上篇中我們介紹在畫面顯示資訊或要有互動按鈕的,效能最好的解法-BJS 2D GUI,它是將 UI 繪製在一張 2D 貼圖上。
BJS GUI 3D 則完全不同,它是一個專門用來創建真正的 3D 交互元件的幫手。用它建的按鈕、滑桿等都是由一個或多個 Mesh 組成的,具有體積、可以被燈光照射,並遵循 3D 空間的物理規則。因此可以更好的融入場景之中,更能有沉浸感。並且它特化了交互邏輯和佈局管理器這塊,內建自動化,因此又比自己建 Box 和 Cylinder能更好的控制。它自動做了哪些呢?
onPointerEnter
(就像是CSS的hover)和按下 onPointerDown
時,會自動產生顏色變化或下沉的動畫。onPointerClickObservable
,無需手動寫 Ray。可以看playground的這個案例,
用短短的程式碼,就有多個排成弧狀,且內建懸停和按下的動畫效果
要使用GUI 3D 就需要先初始化一個GUI 3D 管理器 GUI3DManager
,它將負責管理所有 3D UI 元素的互動。管理器只需要場景就能運作。實例化後管理器會建立一個實用程式層,該層是一個特定的子場景,所有要控制的Mesh的渲染都會被託管於此。
const manager = new BABYLON.GUI.GUI3DManager(scene);
所有的 3D UI 元件(按鈕、滑桿、面板)都繼承自Control3D,且都提供以下函數來處理控制項:
addControl()
:新增控制件containsControl()
:取得一個布林值,指示給定控制項是否在根子清單中removeControl()
:從根子清單中刪除控制件優化效能tips:在自動排版的情況下,由於每做一次addControl()
就會更新一次佈局,所以當有要做很多次addControl()
來連續添加的時候,可以透過container.blockLayout = true;
這段來暫時停止面板的自動佈局,等全都加好了之後再佈局container.blockLayout = false;
。來藉此優化效能
像是這樣:
JavaScript
panel.blockLayout = true;
for (let index = 0; index < 30; index++) {
const button = new BABYLON.GUI.Button3D("click me");
panel.addControl(button);
}
panel.blockLayout = false;
特別的Button 3D
值得注意的是Button3D是個特殊的Control3D子類。他既有Mesh實體,也有2D介面的貼皮能讓文字清楚,還有自動交互的邏輯!堪稱完美!
const panel = new BABYLON.GUI.CylinderPanel();
panel.radius = 5;